import { rdsRequest,rdsRequestAsync, getRdsUrl } from './rdsServices';
import service from "../common/service";
import { billCheck } from './useBillCheck';


const getMapFun = (mapping) => {

    const mapfun = typeof mapping === 'function' ? mapping : async (item) => {
        const row = {};

        const map = new Map((mapping || []).map(map => {
            const [first, ...others] = map;
            return [first, [...others]]
        }))
        map.forEach((mapKeys, key) => {
            mapKeys.forEach((mapKey, index) => {
                (mapKey && (index === 0 || item[mapKey])) ? row[key] = (((typeof row[key] === 'number') && (item[mapKey] === undefined || item[mapKey] == null)) ? 0 : item[mapKey]) : false
            })
        })
        return row;
    }

    return mapfun;
}

const defaultMapping = [
    ['c_gcode', 'c_gcode'],
    ['c_gname', 'c_name'],
    ['c_gname_en', 'c_name_en'],
    ['c_adno', 'c_g_adno'],
    ['c_adname', 'c_g_adno_name'],
    ['c_adname_en', 'c_g_adno_name_en'],
    ['c_ccode', 'c_g_ccode'],
    ['c_cname', 'c_g_ccode_name'],
    ['c_cname_en', 'c_g_ccode_name_en'],
    ['c_provider', 'c_provider'],
    ['c_provider_name', 'c_provider_name'],
    ['c_bcode', 'c_bcode'],
    ['c_bname', 'c_bcode_name'],
    ['c_bname_en', 'c_bcode_name_en'],
    ['c_unit_type', 'c_unit_type'],
    ['c_barcode', 'c_barcode'],
    ['c_n', 'c_n'],
    ['c_introduce_status', 'c_g_introduce_status'],
    ['c_price', 'c_price'],
    ['c_g_status', 'c_g_status', 'c_gds_status'],
    ['c_d_type', 'c_d_type'],
    ['c_s_mode', 'c_s_mode'],
    ['c_gds_flag', 'c_gds_flag']
];


const validateGds = async ({
    url,
    uniqueKey,
    billType = '',
    args, // 如果不是通过录入方式进行验证商品不存在row时，row不可为空，传{}
    //操作类型 string
    operType = 'G',
    // 检查类型string
    checkType = 'D',
    head = {},
    // 明细的映射参数
    detail = [],
    // 返回数据立即回调，取消后续返回
    callback = (async (item) => { cancel, message, dataItem }),
    // 自定义新增行方法， successItems:对成功的数据mapping映射之后的数据，failData：服务返回的数据callback之后的失败数据
    // customAddRow = (successItems, failData) => Promise,
    // 完成之后进行操作  successData：服务返回的数据callback之后的成功数据，successItems:对成功的数据mapping映射之后的数据
    completeCallback = (successData, successItems) => void {},
    // 映射集合，[返回字段，明细字段]
    mapping = defaultMapping,
    listManager = [],
    initRow = async() => {},
    // currentRow = {},
    // 商品编码是否允许重复
    allowRepeat = true,
    // 商品条码是否允许重复
    allowBarcodeRepeat = true,
    // 只能通过商品编码进行验证
    isOnlyGcode = false,
    // 保留原数据行中的字段，主要是多行处理时 string[]
    keep = [],
    // 商品编码所在字段
    gdsFieldName = 'c_gcode',
    // 明细中是否存在机构字段，默认为true；
    // 应用场景：配送(通知)单进行商品验证时，level值为4，但是明细中不存在机构字段，验证商品重复时就不应该再验证机构相等的条件，所以此时应配置为false
    detailHasStore = true
}) => {
    const rdsUrl = getRdsUrl();
    const _url = url || rdsUrl.scApi

    let { fieldName, row, newValue, } = args;
    let gcode = '';

    if (fieldName === gdsFieldName) {
        if (isOnlyGcode && newValue) {

            const result = await rdsRequest(_url, 'Rds公共服务', 'GetGcodesByCodes', { code: newValue })
            gcode = result || '';

        } else {
            gcode = newValue
        }
    }
    else {
        gcode = row[gdsFieldName];
    }
    if (gcode) {
        //const value = gcode;
        const headModel = typeof (head) === 'function' ? head(row, gcode) : head;
        //TODO: 将机构转化为门店编码
        if (Array.isArray(headModel.code)) {
            if (headModel.code?.length > 0 && headModel.level === '1') {
                const result = await rdsRequest(_url, 'Rds公共服务', 'ResolveStoreId', headModel.code.join(','))
                headModel.code = result.map(a => a.c_store_id);
            }
        } else {
            headModel.code = headModel.level === '4' ? [] : [headModel.code || ''];
        }

        const detailArray = [];
        // gcode.replaceAll('，', ',').split(',').map((code, sort) => {
        let defaultValues = []
        if (Array.isArray(detail)) {
            defaultValues = [{
                provider: fieldName === 'c_provider' ? newValue : (detail.includes('c_provider') ? row['c_provider'] : ''),
                adno: fieldName === 'c_adno' ? newValue : (detail.includes('c_adno') ? row['c_adno'] : ''),
                ccode: fieldName === 'c_ccode' ? newValue : (detail.includes('c_ccode') ? row['c_ccode'] : ''),
                bcode: fieldName === 'c_bcode' ? newValue : (detail.includes('c_bcode') ? row['c_bcode'] : ''),
                store: fieldName === 'c_store_id' ? newValue : (detail.includes('c_store_id') ? row['c_store_id'] : ''),
                con_no: fieldName === 'c_con_no' ? newValue : (detail.includes('c_con_no') ? row['c_con_no'] : ''),
                con_type: fieldName === 'c_con_type' ? newValue : (detail.includes('c_con_type') ? row['c_con_type'] : ''),
            }]
        } else if (detail && typeof detail === 'function') {
            defaultValues = detail(row, gcode)
        }
        if (detail) {
            detailArray.push(...defaultValues.map(detail => ({
                sort: 0,
                code: gcode,
                gcode: '',
                ...detail
            })))
        } else {
            detailArray.push({
                sort: 0,
                code: isOnlyGcode ? '' : gcode,
                gcode: isOnlyGcode ? gcode : ''
            })
        }
        // })

        const checkin = {
            head: {
                ...headModel,
                level: headModel.level || '1',
                value_mode: headModel.value_mode || 'F',
                sample_code: headModel.sample_code || ''
            },
            details: detailArray
        };
        // 调用单据检查，验证商品明细默认G操作类型
        const resultBC = await billCheck(_url, uniqueKey, {
            oper_type: operType,
            check_type: checkType,
            bill_type: billType,
            ...checkin
        })
        if (resultBC.length === 0) {
            uni.showToast({
                duration: 3500,
                icon: 'none',
                title: '没有获取到任何数据，请检查单据验证规则'
            });
            return;
        }
        let resultItems = resultBC;
        if (callback) {
            try {
                const callResult = await callback(resultItems)
                if (callResult && callResult.cancel) {
                    if (callResult.message) {
                        args.retValue = args.oldValue;
                        return {
                            retValue: args.oldValue,
                            validated: false,
                            message: callResult.message
                        }
                    }
                    return;
                }
                if (callResult && callResult.dataItem) {
                    resultItems = callResult.dataItem;
                }
            } catch (error) {
                console.log(error);
            }
        }
        const level = checkin?.head?.level || '1';
        const mapfun = getMapFun(mapping);
        if (!allowRepeat) {
            resultItems.forEach(item => {
                const existsGds = listManager.some(f => f[gdsFieldName] === item[gdsFieldName]
                    && (level !== '4' || (level === '4' && (!detailHasStore || f['c_store_id'] === item['c_store_id']))))
                existsGds ? item['c_chk_msginfo'] = `商品[${item[gdsFieldName]}]已经在明细中存在` : false
            })
        }
        if (!allowBarcodeRepeat) {
            resultItems.forEach(item => {
                const existsBar = listManager.some(f => f['c_barcode'] === item['c_barcode'] && item['c_barcode']
                    && (level !== '4' || (level === '4' && (!detailHasStore || f['c_store_id'] === item['c_store_id']))))
                existsBar ? item['c_chk_msginfo'] = `条码[${item['c_barcode']}]已经在明细中存在` : false
            })
        }

        const failItems = resultItems.filter(item => item['c_chk_msginfo']);
        let successItems = resultItems.filter(item => !item['c_chk_msginfo']);
        let success = await Promise.all(successItems?.map(async (item) => await mapfun(item)));
        if (resultItems.length === 1 && failItems.length === 1) {
            uni.showToast({
                duration: 3500,
                icon: 'none',
                title: `${failItems[0].c_chk_msginfo}`
            });
            return;
        }

        // 如果存在自定义新增行方法,则走自定义新增方法
        // if (customAddRow) {
        //     return customAddRow(success, successItems);
        // }

        let validateResult = null;
        if (resultItems.length === 1 && success.length === 1) {
            // 对于不存在row的数据，构造行数据
            // if (row['_key'] === undefined) {
            //     row = initRow && await initRow(listManager, Number(0));
            //     listManager.push(row);
            // }
            // 第一行数据重新赋值到当前的编辑行
            listManager.push(row);
            const newRow = success[0];
            newRow && Object.keys(newRow).forEach(key => row[key] = newRow[key]);

            // if (fieldName === gdsFieldName) {
            //     args.retValue = newRow[gdsFieldName];
            //     validateResult = {
            //         validated: true,
            //         retValue: newRow[gdsFieldName]
            //     };
            // }
            if (completeCallback) {
                completeCallback(successItems, success);
            }
            return row;
        } else if (resultItems.length > 1) {
            // 删除当前行
            if (row['c_gcode']) {
                listManager.remove([row])
            }
            if (success.length > 1) {
                const successRows = [];
                for (let index in success) {
                    const item = success[index];
                    console.log('item', item);
                    const newRow = initRow() && await initRow(Number(index))
                    Object.keys(item).forEach(key => newRow[key] = item[key]);
                    keep.forEach(key => newRow[key] = row[key]); // 保留原有字段
                    successRows.push(newRow)
                }
                success.length && listManager.push(...successRows);
                console.log('listManager', listManager);
            } else if (success.length === 1) {
                // 对于不存在row的数据，构造行数据
                if (!row['c_gcode']) {
                    // row = initRow() && await initRow(listManager, Number(0))
                    listManager.push([row]);
                }
                // 第一行数据重新赋值到当前的编辑行
                const firstRow = success[0]
                firstRow && Object.keys(firstRow).forEach(key => row[key] = firstRow[key]);
                if (fieldName === gdsFieldName) {
                    args.retValue = firstRow[gdsFieldName];
                    validateResult = {
                        validated: true,
                        retValue: firstRow[gdsFieldName]
                    }
                }
            } else {
                args.retValue = args.oldValue;
                validateResult = {
                    validated: true,
                    retValue: args.oldValue
                }
            }
            // 存在失败的失败则直接表格展示
            // failItems.length > 0 && showResult(failItems);
        } else {
            uni.showToast({
                duration: 3500,
                icon: 'none',
                title: '没有返回数据'
            });
            return null;
        }
    }
}



//验证机构和仓库是否对应
const validateStoresAndWno = async ({ value, wno }) => {
    const rdsUrl = getRdsUrl();

    if (value && wno) {
        const result = await rdsRequest(rdsUrl.bcApi, 'Rds公共服务', 'GetWnoInfo', {
            code: wno,
            storeId: value
        })
        return result;
    }
};

//验证机构
const validateStores = async (args, extend = {}) => {
    const rdsUrl = getRdsUrl();
    const { fieldName, row = {}, newValue } = args;
    const { type, ischecklimit, firstValueMode } = extend;

    if (fieldName === 'c_store_id' && newValue) {
        const result = await rdsRequest(rdsUrl.bcApi, 'Rds公共服务', 'GetStoreInfos', {
            code: newValue,
            storeType: type,
            isLimit: ischecklimit
        });
        try {
            if (firstValueMode) {
                if (result.length === 1 && result[0].c_type === '2') {
                    row['c_value_mode'] = 'F';
                    row["c_sample_code"] = '';
                    row["c_sample_code_name"] = '';
                }
            } else {
                if (result.length === 1 && ['2', '3'].includes(result[0].c_type)) {
                    row["c_value_mode"] = 'F';
                    row["c_sample_code"] = '';
                    row["c_sample_code_name"] = '';
                    row['c_sample_name_en'] = '';
                }
            }
        } catch (error) {
            console.log(error);
        }
        return result[0];
    }
};
/**
 * 判断是否为数字
 * @param {*} inputNum 
 */
const checkNum = (inputNum:any) => {
    if (!isNaN(parseFloat(inputNum)) && isFinite(inputNum)) {
      return true
    }
    return false;
  }

  const checkIntNum = (inputNum:any) => {
    let pattern = /^[0-9]\d*$/
    if (!pattern.test(inputNum)) {
      return false
    }
    return true;
  }
/**
 * @description 在商品编码处录入批号 或者在批号处直接录入批号 验证
*/
const ValiSerialGcode = async (param: {
	storeId?: string,
	serialNo: string,
	adno?: string,
	wno?: string,
	gcode?: string,
	shelfNo?: string
}) => {
	const { storeId, serialNo, adno, wno, gcode, shelfNo } = param;

    const rdsUrl = getRdsUrl();
	if (!serialNo) {
		return {
			validated: true,
			retValue: serialNo
		};
	}
	if (!gcode && (serialNo.includes(',') || serialNo.includes('，'))) {
		return {
			validated: true,
			retValue: serialNo
		};
	}

	const valiSerialRes = await rdsRequestAsync(rdsUrl.scApi,'Rds公共服务', 'ValiSerialNoGcode', {
		storeId: storeId,
		adno: adno,
		wno: wno,
		serialNo: serialNo,
		gcode: gcode,
		shelfNo: shelfNo
	});
	if (valiSerialRes.HasException) {
		return {
			validated: false,
			message: valiSerialRes.Exception.Message
		}
	}

	return {
		validated: true,
		retValue: valiSerialRes.ObjectData || serialNo
	};
}
export {
    defaultMapping,
    validateGds,
    validateStoresAndWno,
    validateStores,
    checkNum,
    checkIntNum,
	ValiSerialGcode
};
